/* 
  单向链表
  01 node + head + null 
  02 head --->null 
  03 size 

  04 next element

  05 增加 删除 修改 查询 清空 
*/

class Node {
    constructor(element, next) {
        this.element = element;
        this.next = next;
    }
}

class LinkedList {
    constructor(head, size) {
        this.head = null
        this.size = 0
    }
    _getNode(index) {
        if (index < 0 || index >= this.size) {
            throw new Error('越界了')
        }
        let currentNode = this.head
        for (let i = 0; i < index; i++) {
            //向后修改next指向
            currentNode = currentNode.next
        }
        return currentNode
    }
    add(index, element) {
        if (arguments.length == 1) {
            element = index
            index = this.size
        }
        if (index < 0 || index > this.size) {
            throw new Error('cross the border')
        }
        if (index == 0) {
            // 保存原有 head 的指向作为new node的指向，新的heade指向我们新创建的newNode
            let head = this.head
            this.head = new Node(element, head)
        } else {
            let prevNode = this._getNode(index - 1)
            prevNode.next = new Node(element, prevNode.next)
        }
        this.size++
    }
    remove(index) {
        let rmNode = null
        if (index == 0) {
            //删除的是第一个修改head指向
            rmNode = this.head
            if (!rmNode) {
                return undefined
            }
            this.head = rmNode.next
        } else {
            //其他删除当前节点上一个节点 指向当前节点的下一个节点
            let prevNode = this._getNode(index - 1)
            rmNode = prevNode.next
            prevNode.next = rmNode.next
        }
        this.size--
        return rmNode
    }
    set(index, element) {
        let node = this._getNode(index)
        node.element = element
    }
    get(index) {
        return this._getNode(index)
    }
    clear() {
        this.head = null
        this.size = 0
    }
}

class Queue {
    constructor() {
        this.linkedList = new LinkedList()
    }
    enQueue(data) {
        this.linkedList.add(data)
    }
    deQueue() {
        return this.linkedList.remove(0)
    }
}

// const q = new Queue()

// q.enQueue('node1')
// q.enQueue('node2')

// let a = q.deQueue()
// a = q.deQueue()
// a = q.deQueue()

// console.log(a)

/* const l1 = new LinkedList()
l1.add("node1")
l1.add("node2")
l1.add(1,"node3")
l1.remove(1)
l1.set(1,"node2-2")
l1.clear()
// console.log(l1.get(1));
console.log(l1); */

module.exports = Queue